package com.airlenet.codetoword;

import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Word文档生成器 - 软著申请专用
 */
public class WordDocumentGenerator {
    
    // 软著代码提交配置
    private static final int MAX_PAGES = 60; // 最大页数限制
    private static final int MIN_LINES_PER_PAGE = 50; // 每页最少行数
    private static final int LINES_PER_PAGE = 55; // 每页目标行数
    
    /**
     * 生成Word文档 - 软著申请专用
     * @param codeFiles 代码文件列表
     * @param outputPath 输出文件路径
     * @param basePath 基础路径，用于计算相对路径
     */
    public void generateDocument(List<CodeFile> codeFiles, String outputPath, String basePath) throws IOException {
        try (XWPFDocument document = new XWPFDocument()) {
            // 创建标题
            createTitle(document, "软件源代码文档");
            
            // 创建摘要表格
            createSummaryTable(document, codeFiles, basePath);
            
            // 计算总代码行数
            int totalLines = calculateTotalLines(codeFiles);
            boolean needPagination = totalLines > MAX_PAGES * MIN_LINES_PER_PAGE;
            
            // 添加分页说明
            createPaginationNotice(document, needPagination, totalLines);
            
            // 为每个代码文件创建章节（智能分页）
            if (needPagination) {
                // 超过60页，提交前30页和后30页
                createPagedCodeSections(document, codeFiles, basePath);
            } else {
                // 不足60页，提交完整代码
                for (CodeFile codeFile : codeFiles) {
                    createCodeFileSection(document, codeFile, basePath, true);
                }
            }
            
            // 保存文档
            try (FileOutputStream out = new FileOutputStream(outputPath)) {
                document.write(out);
            }
        }
    }
    
    /**
     * 计算总代码行数
     */
    private int calculateTotalLines(List<CodeFile> codeFiles) {
        int total = 0;
        for (CodeFile codeFile : codeFiles) {
            total += countLines(codeFile.getContent());
        }
        return total;
    }
    
    /**
     * 创建分页说明
     */
    private void createPaginationNotice(XWPFDocument document, boolean needPagination, int totalLines) {
        XWPFParagraph noticeParagraph = document.createParagraph();
        XWPFRun noticeRun = noticeParagraph.createRun();
        
        if (needPagination) {
            noticeRun.setText(String.format("说明：源代码总行数 %d 行，超过 %d 页限制，根据软著要求提交前30页和后30页代码。", 
                totalLines, MAX_PAGES));
        } else {
            noticeRun.setText(String.format("说明：源代码总行数 %d 行，不足 %d 页限制，提交完整源代码。", 
                totalLines, MAX_PAGES));
        }
        noticeRun.setBold(true);
        noticeRun.setColor("FF0000");
        noticeRun.setFontSize(12);
        
        document.createParagraph();
    }
    
    /**
     * 获取相对路径
     * @param filePath 文件完整路径
     * @param basePath 基础路径
     * @return 相对路径
     */
    private String getRelativePath(String filePath, String basePath) {
        if (filePath.startsWith(basePath)) {
            return filePath.substring(basePath.length()).replace("\\", "/");
        }
        return filePath;
    }
    
    private void createTitle(XWPFDocument document, String title) {
        // 软件著作权声明
        XWPFParagraph copyrightParagraph = document.createParagraph();
        copyrightParagraph.setAlignment(ParagraphAlignment.RIGHT);
        XWPFRun copyrightRun = copyrightParagraph.createRun();
        copyrightRun.setText("版权所有 © 2025 Airlenet. 保留所有权利。");
        copyrightRun.setFontSize(9);
        copyrightRun.setItalic(true);
        
        // 主标题
        XWPFParagraph titleParagraph = document.createParagraph();
        titleParagraph.setAlignment(ParagraphAlignment.CENTER);
        
        XWPFRun titleRun = titleParagraph.createRun();
        titleRun.setText(title);
        titleRun.setBold(true);
        titleRun.setFontSize(20);
        titleRun.setFontFamily("宋体");
        
        // 副标题
        XWPFParagraph subtitleParagraph = document.createParagraph();
        subtitleParagraph.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun subtitleRun = subtitleParagraph.createRun();
        subtitleRun.setText("软件源代码文档");
        subtitleRun.setBold(true);
        subtitleRun.setFontSize(14);
        
        // 添加空行
        document.createParagraph();
    }
    
    private void createSummaryTable(XWPFDocument document, List<CodeFile> codeFiles, String basePath) {
        // 创建表格标题
        XWPFParagraph tableTitle = document.createParagraph();
        XWPFRun tableTitleRun = tableTitle.createRun();
        tableTitleRun.setText("源代码文件统计表");
        tableTitleRun.setBold(true);
        tableTitleRun.setFontSize(14);
        
        // 统计信息
        XWPFParagraph statsParagraph = document.createParagraph();
        XWPFRun statsRun = statsParagraph.createRun();
        statsRun.setText(String.format("总文件数: %d", codeFiles.size()));
        statsRun.setFontSize(10);
        statsRun.setItalic(true);
        
        // 创建表格
        XWPFTable table = document.createTable();
        
        // 设置表格宽度
        CTTblWidth tblWidth = table.getCTTbl().addNewTblPr().addNewTblW();
        tblWidth.setType(STTblWidth.DXA);
        tblWidth.setW(9000);
        
        // 创建表头
        XWPFTableRow headerRow = table.getRow(0);
        headerRow.getCell(0).setText("序号");
        headerRow.addNewTableCell().setText("文件名");
        headerRow.addNewTableCell().setText("文件类型");
        headerRow.addNewTableCell().setText("相对路径");
        headerRow.addNewTableCell().setText("代码行数");
        
        // 填充数据
        int index = 1;
        for (CodeFile codeFile : codeFiles) {
            XWPFTableRow dataRow = table.createRow();
            dataRow.getCell(0).setText(String.valueOf(index++));
            dataRow.getCell(1).setText(codeFile.getFileName());
            dataRow.getCell(2).setText(codeFile.getFileType().toUpperCase());
            dataRow.getCell(3).setText(getRelativePath(codeFile.getFilePath(), basePath));
            dataRow.getCell(4).setText(String.valueOf(countLines(codeFile.getContent())));
        }
        
        document.createParagraph();
    }
    
    private int countLines(String content) {
        if (content == null || content.isEmpty()) {
            return 0;
        }
        return content.split("\r\n|\r|\n").length;
    }
    
    /**
     * 智能分页处理（前30页+后30页）
     */
    private void createPagedCodeSections(XWPFDocument document, List<CodeFile> codeFiles, String basePath) {
        List<String> allCodeLines = new ArrayList<>();
        
        // 收集所有代码行，并添加文件信息头部
        for (CodeFile codeFile : codeFiles) {
            // 为每个文件添加文件信息头部
            allCodeLines.add("// =========================================");
            allCodeLines.add("// 文件信息: " + codeFile.getFileName());
            allCodeLines.add("// 文件路径: " + getRelativePath(codeFile.getFilePath(), basePath));
            allCodeLines.add("// 文件大小: " + codeFile.getContent().length() + " bytes");
            allCodeLines.add("// 代码行数: " + countLines(codeFile.getContent()));
            allCodeLines.add("// 文件类型: " + codeFile.getFileType().toUpperCase());
            allCodeLines.add("// =========================================");
            allCodeLines.add("");
            
            String[] lines = codeFile.getContent().split("\r\n|\r|\n");
            for (String line : lines) {
                allCodeLines.add(line);
            }
            allCodeLines.add(""); // 文件间添加空行
        }
        
        int totalPages = (int) Math.ceil((double) allCodeLines.size() / LINES_PER_PAGE);
        
        if (totalPages <= MAX_PAGES) {
            // 不足60页，提交完整代码
            for (CodeFile codeFile : codeFiles) {
                createCodeFileSection(document, codeFile, basePath, true);
            }
        } else {
            // 超过60页，提交前30页和后30页
            createFirst30Pages(document, allCodeLines, codeFiles, basePath);
            createLast30Pages(document, allCodeLines, codeFiles, basePath, totalPages);
        }
    }
    
    /**
     * 创建前30页代码
     */
    private void createFirst30Pages(XWPFDocument document, List<String> allCodeLines, 
                                   List<CodeFile> codeFiles, String basePath) {
        XWPFParagraph sectionTitle = document.createParagraph();
        XWPFRun titleRun = sectionTitle.createRun();
        titleRun.setText("=== 前30页源代码 ===");
        titleRun.setBold(true);
        titleRun.setFontSize(16);
        titleRun.setColor("0000FF");
        
        int endLine = Math.min(30 * LINES_PER_PAGE, allCodeLines.size());
        List<String> firstPagesLines = allCodeLines.subList(0, endLine);
        createPagedCodeContent(document, firstPagesLines, "前30页");
    }
    
    /**
     * 创建后30页代码
     */
    private void createLast30Pages(XWPFDocument document, List<String> allCodeLines, 
                                  List<CodeFile> codeFiles, String basePath, int totalPages) {
        // 添加分页符和章节标题
        XWPFParagraph pageBreak = document.createParagraph();
        pageBreak.setPageBreak(true);
        
        XWPFParagraph sectionTitle = document.createParagraph();
        XWPFRun titleRun = sectionTitle.createRun();
        titleRun.setText("=== 后30页源代码 ===");
        titleRun.setBold(true);
        titleRun.setFontSize(16);
        titleRun.setColor("0000FF");
        
        int startLine = Math.max(0, allCodeLines.size() - 30 * LINES_PER_PAGE);
        List<String> lastPagesLines = allCodeLines.subList(startLine, allCodeLines.size());
        createPagedCodeContent(document, lastPagesLines, "后30页");
    }
    
    /**
     * 创建分页代码内容
     */
    private void createPagedCodeContent(XWPFDocument document, List<String> codeLines, String sectionName) {
        int currentLine = 0;
        int pageNumber = 1;
        
        while (currentLine < codeLines.size()) {
            int endLine = Math.min(currentLine + LINES_PER_PAGE, codeLines.size());
            List<String> pageLines = codeLines.subList(currentLine, endLine);
            
            // 确保最后一页是完整的功能模块
            if (endLine == codeLines.size()) {
                // 检查是否需要调整最后一页的行数以确保完整性
                endLine = adjustLastPageForCompleteness(codeLines, currentLine, endLine);
                pageLines = codeLines.subList(currentLine, endLine);
            }
            
            // 创建页面标题
            XWPFParagraph pageTitle = document.createParagraph();
            XWPFRun pageTitleRun = pageTitle.createRun();
            pageTitleRun.setText(String.format("%s - 第%d页 (行%d-%d)", 
                sectionName, pageNumber, currentLine + 1, endLine));
            pageTitleRun.setBold(true);
            pageTitleRun.setFontSize(12);
            
            // 创建代码内容
            XWPFParagraph codeBlock = document.createParagraph();
            codeBlock.setAlignment(ParagraphAlignment.LEFT);
            codeBlock.setIndentationLeft(200);
            
            XWPFRun codeRun = codeBlock.createRun();
            codeRun.setFontFamily("Courier New");
            codeRun.setFontSize(9); // 较小字体确保每页50行以上
            
            for (String line : pageLines) {
                codeRun.setText(line);
                codeRun.addBreak(); // 显式添加换行符
            }
            
            // 如果不是最后一页，添加分页符
            if (endLine < codeLines.size()) {
                XWPFParagraph breakParagraph = document.createParagraph();
                breakParagraph.setPageBreak(true);
            }
            
            currentLine = endLine;
            pageNumber++;
        }
    }
    
    /**
     * 调整最后一页以确保功能模块完整性
     */
    private int adjustLastPageForCompleteness(List<String> codeLines, int startLine, int proposedEndLine) {
        if (proposedEndLine == codeLines.size()) {
            return proposedEndLine; // 已经是最后一行
        }
        
        // 检查当前结束位置是否在完整的功能模块结尾
        for (int i = proposedEndLine; i < Math.min(proposedEndLine + 10, codeLines.size()); i++) {
            String line = codeLines.get(i).trim();
            // 如果遇到明显的模块结尾（如右大括号、空行后的注释等）
            if (line.equals("}") || line.startsWith("//") || line.startsWith("/*") || 
                line.isEmpty() || line.startsWith("*/")) {
                return i + 1; // 包含这个结尾行
            }
        }
        
        return proposedEndLine;
    }
    
    private void createCodeFileSection(XWPFDocument document, CodeFile codeFile, String basePath, boolean withPagination) {
        // 文件标题
        XWPFParagraph fileTitle = document.createParagraph();
        fileTitle.setAlignment(ParagraphAlignment.LEFT);
        
        XWPFRun fileTitleRun = fileTitle.createRun();
        fileTitleRun.setText(codeFile.getFileName() + " (" + codeFile.getFileType() + ")");
        fileTitleRun.setBold(true);
        fileTitleRun.setFontSize(16);
        fileTitleRun.setFontFamily("宋体");
        
        // 文件信息头部
        XWPFParagraph infoParagraph = document.createParagraph();
        XWPFRun infoRun = infoParagraph.createRun();
        infoRun.setText("文件信息:");
        infoRun.setBold(true);
        
        // 文件路径（显示相对路径）
        XWPFParagraph pathParagraph = document.createParagraph();
        pathParagraph.setIndentationLeft(200);
        XWPFRun pathRun = pathParagraph.createRun();
        pathRun.setText("• 路径: " + getRelativePath(codeFile.getFilePath(), basePath));
        pathRun.setFontSize(10);
        
        // 文件大小和行数
        XWPFParagraph statsParagraph = document.createParagraph();
        statsParagraph.setIndentationLeft(200);
        XWPFRun statsRun = statsParagraph.createRun();
        statsRun.setText("• 大小: " + codeFile.getContent().length() + " 字符");
        statsRun.setFontSize(10);
        
        XWPFParagraph linesParagraph = document.createParagraph();
        linesParagraph.setIndentationLeft(200);
        XWPFRun linesRun = linesParagraph.createRun();
        linesRun.setText("• 行数: " + countLines(codeFile.getContent()) + " 行");
        linesRun.setFontSize(10);
        
        // 代码内容
        XWPFParagraph codeParagraph = document.createParagraph();
        codeParagraph.setAlignment(ParagraphAlignment.LEFT);
        
        XWPFRun codeRun = codeParagraph.createRun();
        codeRun.setText("代码内容:");
        codeRun.setBold(true);
        
        // 代码块
        XWPFParagraph codeBlock = document.createParagraph();
        codeBlock.setAlignment(ParagraphAlignment.LEFT);
        codeBlock.setIndentationLeft(400);
        
        XWPFRun codeContentRun = codeBlock.createRun();
        codeContentRun.setText(codeFile.getContent());
        codeContentRun.setFontFamily("Courier New");
        codeContentRun.setFontSize(9); // 较小字体确保每页50行以上
        
        // 添加分页符（如果需要）
        if (withPagination) {
            XWPFParagraph pageBreak = document.createParagraph();
            pageBreak.setPageBreak(true);
        }
    }
}